var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { jsx, toJs } from 'estree-util-to-js';
import { remark } from 'remark';
import { remove } from 'unist-util-remove';
import { removePosition } from 'unist-util-remove-position';
import { MdxImportSpecifier } from '../../types/mdx/index.js';
import { coreRemarkMdxPlugins } from '../remark.js';
import { isMdxJsEsm, estreeIsProgram, isImportDeclaration } from '../utils.js';
/**
  An import like "import {Chart} from './chart.mdx'" looks like this in the AST:
  {
    type: 'mdxjsEsm',
    data: {
      estree: {
        type: 'Program',
        sourceType: 'module',
        body: [{
          type: 'ImportDeclaration',
          source: {
            value: './chart.mdx'
          },
          specifiers: [{
            type: 'ImportSpecifier',
            local: {
              type: 'Identifier',
              name: 'Chart'
            }
          }]
        }]
      }
    }
  }
 * this function takes in a string finds and removes imports in it (by detecting the node with the above characteristics)
 * @param content mdx file content
 * @returns importPaths - an array of the imports
 * content - the mdx file content with stripped imports
 */
export const findAndRemoveImports = (content) => __awaiter(void 0, void 0, void 0, function* () {
    const importMap = {};
    const strippedContent = yield remark()
        .use(coreRemarkMdxPlugins)
        .use(() => (tree) => {
        remove(tree, (node) => {
            var _a;
            if (isMdxJsEsm(node) && estreeIsProgram(node)) {
                const newBody = [];
                for (const bodyChild of node.data.estree.body) {
                    if (isImportDeclaration(bodyChild) && typeof bodyChild.source.value === 'string') {
                        const importDeclaration = {
                            source: bodyChild.source.value,
                            specifiers: bodyChild.specifiers.map((specifier) => {
                                const isRenamedImportSpecifier = specifier.type === 'ImportSpecifier' &&
                                    specifier.imported.name != specifier.local.name;
                                return Object.assign({ type: isRenamedImportSpecifier
                                        ? MdxImportSpecifier.RenamedImportSpecifier
                                        : specifier.type, name: isRenamedImportSpecifier ? specifier.imported.name : specifier.local.name }, (isRenamedImportSpecifier && {
                                    renamedName: specifier.local.name,
                                }));
                            }),
                        };
                        if (importMap[importDeclaration.source] == undefined) {
                            importMap[importDeclaration.source] = importDeclaration.specifiers;
                        }
                        else {
                            (_a = importMap[importDeclaration.source]) === null || _a === void 0 ? void 0 : _a.push(...importDeclaration.specifiers);
                        }
                    }
                    else {
                        newBody.push(bodyChild);
                    }
                }
                if (newBody.length != 0) {
                    node.data.estree.body = newBody;
                    if (node.value) {
                        delete node.value;
                    }
                    removePosition(node);
                    const newValue = toJs(node.data.estree, { handlers: jsx }).value;
                    node.value = newValue;
                    return false;
                }
                return true;
            }
        });
        return tree;
    })
        .process(content);
    return { importMap, content: String(strippedContent) };
});
